package com.tongji.diy.model.furniturePlacementOptimization.assembleComplement
{
	import com.tongji.diy.model.furniturePlacementOptimization.OptimizationParameter;
	import com.tongji.diy.model.furniturePlacementOptimization.complementStructs.CompConverBlock;
	import com.tongji.diy.utils.OptimizationMath;
	
	import flash.geom.Matrix;
	import flash.geom.Point;

	public class ConversationBlock extends FurnitureBlock
	{
		private var _seatList:Vector.<FurnitureBase>;
		private var compSeatList:Vector.<CompConverBlock> = new Vector.<CompConverBlock>;
		private var _blockWidth:Number = 0;
		private var _blockLength:Number = 0;
		
		public function ConversationBlock(furnitrueIndex:int, furnitureClass:int, aganistWall:Boolean, seatList:Vector.<FurnitureBase>,length:Number=0, width:Number=0, height:Number=0)
		{
			super(furnitrueIndex, furnitureClass, aganistWall, length, width, height);
			this._seatList = seatList;
			//按照面积从大到小顺序进行排序
			this._seatList.sort(sort);
			buildBlock();
			update();
		}
		
		private function buildBlock():void
		{
			//var rectLT:Point = new Point(-OptimizationParameter.CONVERSATION_DISTANCE/2, OptimizationParameter.CONVERSATION_DISTANCE/2);
			//var rectRB:Point = new Point(OptimizationParameter.CONVERSATION_DISTANCE/2, -OptimizationParameter.CONVERSATION_DISTANCE/2);
			//先摆放第一个（最大的一个），打破rect长宽的平衡。
			var width:Number = OptimizationParameter.CONVERSATION_DISTANCE;
			var length:Number = OptimizationParameter.CONVERSATION_DISTANCE;
			
			var seat:FurnitureBase = _seatList.shift();
			//初始化4个方向的列表，分别是后右左前
			OptimizationMath.assert(_seatList.length < 4);
			compSeatList.push(new CompConverBlock(),new CompConverBlock(),new CompConverBlock(),new CompConverBlock());
			compSeatList[0].list.push(seat);
			width = Math.max(seat.width , width);
			while(_seatList.length)
			{
				//备选的两个seat
				var tempSeatA:FurnitureBase = finest(width);//下方向
				var tempSeatB:FurnitureBase = finest(length);//左右方向
				if((!compSeatList[3].list.length && Math.abs(tempSeatA.width - width) <= Math.abs(tempSeatB.width - length))||
					(compSeatList[1].length && compSeatList[2].length))
				{
					if(!compSeatList[3].list.length)
					{
						compSeatList[3].list.push(tempSeatA);
					}
					width = Math.max(tempSeatA.width /*+ 2 * (seat.accLength - seat.length)*/, width);
					_seatList.splice(_seatList.indexOf(tempSeatA),1);
				}
				else 
				{
					if(!compSeatList[1].list.length)
					{
						compSeatList[1].list.push(tempSeatB);
					}
					else if(!compSeatList[2].list.length)
					{
						compSeatList[2].list.push(tempSeatB);
					}
					length = Math.max(tempSeatB.width /*+ 2*(seat.accLength - seat.length)*/, length);
					_seatList.splice(_seatList.indexOf(tempSeatB),1);
				}
			}
			
			if(compSeatList[0].length)
			{
				compSeatList[0].list[0].x = 0;
				compSeatList[0].list[0].y = length/2 + compSeatList[0].list[0].accLength - compSeatList[0].list[0].length/2
				compSeatList[0].list[0].angle = 0;
				_seatList.push(compSeatList[0].list[0]);
				//trace("compSeatList[0].list[0]",compSeatList[0].list[0].x,compSeatList[0].list[0].y)
			}
			
			if(compSeatList[1].length)
			{
				compSeatList[1].list[0].x = width/2 + compSeatList[1].list[0].accLength - compSeatList[1].list[0].length/2;
				compSeatList[1].list[0].y = 0;
				compSeatList[1].list[0].angle = Math.PI/2;
				_seatList.push(compSeatList[1].list[0]);
				//trace("compSeatList[1].list[0]",compSeatList[1].list[0].x,compSeatList[1].list[0].y)
			}
			
			if(compSeatList[2].length)
			{
				compSeatList[2].list[0].x = -width/2 - compSeatList[2].list[0].accLength + compSeatList[2].list[0].length/2;
				compSeatList[2].list[0].y = 0;
				compSeatList[2].list[0].angle = -Math.PI/2;
				_seatList.push(compSeatList[2].list[0]);
				//trace("compSeatList[2].list[0]",compSeatList[2].list[0].x,compSeatList[2].list[0].y)
			}
			
			
			if(compSeatList[3].length)
			{
				compSeatList[3].list[0].x = 0;
				compSeatList[3].list[0].y = -length/2 - compSeatList[3].list[0].accLength + compSeatList[3].list[0].length/2;
				compSeatList[3].list[0].angle = Math.PI;
				_seatList.push(compSeatList[3].list[0]);
				//trace("compSeatList[3].list[0]",compSeatList[3].list[0].x,compSeatList[3].list[0].y)
			}
			
		}
		
		private function update():void
		{
			var maxX:Number = -Infinity;
			var maxY:Number = -Infinity;
			var minX:Number = Infinity;
			var minY:Number = Infinity;
			for(var i:int = 0; i < _seatList.length; ++i)
			{
				if(maxX < _seatList[i].accMaxX)
					maxX = _seatList[i].accMaxX;
				if(maxY < _seatList[i].accMaxY)
					maxY = _seatList[i].accMaxY;
				if(minX > _seatList[i].accMinX)
					minX = _seatList[i].accMinX;
				if(minY > _seatList[i].accMinY)
					minY = _seatList[i].accMinY;
			}
			_blockLength = maxY - minY;
			_blockWidth = maxX - minX;
			modifyXY(maxX,minX,maxY,minY);
		}
		
		private function modifyXY(maxX:Number, minX:Number, maxY:Number, minY:Number):void
		{
			for(var i:int = 0; i < _seatList.length; ++i)
			{
				_seatList[i].x -= (maxX + minX)/2;
				_seatList[i].y -= (maxY + minY)/2;
			}
			//test
			trace(_seatList[0].boundingBox[0],_seatList[0].boundingBox[1],_seatList[0].boundingBox[2],_seatList[0].boundingBox[3]);
			trace(_seatList[0].accessibleBox[0],_seatList[0].accessibleBox[1],_seatList[0].accessibleBox[2],_seatList[0].accessibleBox[3]);

		}
		
		//在seatlist中找到宽度最接近num数值的seat
		private function finest(num:Number):FurnitureBase
		{
			var res:FurnitureBase = _seatList[0];
			seatList.forEach(findfinest);
			
			function findfinest(item:FurnitureBase, index:int, v:*):void
			{
				if(Math.abs(item.width - num) < Math.abs(res.width - num))
					res = item;
			}
			
			return res;
		}
		
		private function sort(furA:FurnitureBase, furB:FurnitureBase):int
		{
			if(/*furA.length**/furA.width > /*furB.length**/furB.width)
				return -1;
			return 1;
		}
		
		public override function set x(newX:Number):void
		{
			var tempX:Number = super.x;
			tempX = newX - tempX;
			super.x = newX;
			
			for(var i:int = 0; i < _seatList.length; ++i)
			{
				_seatList[i].x += tempX;
			}
			_accessibleBox = buildAccessOBB(x,y,_blockWidth,_blockLength);
		}
		
		public override function set y(newY:Number):void
		{
			var tempY:Number = super.y;
			tempY = newY - tempY;
			super.y = newY;
			
			for(var i:int = 0; i < _seatList.length; ++i)
			{
				_seatList[i].y += tempY;
			}
			_accessibleBox = buildAccessOBB(x,y,_blockWidth,_blockLength);
		}
		
		public override function set angle(newAngle:Number):void
		{
			var tempangle:Number = super.angle;
			super.angle = newAngle;
			
			var m1:Matrix = new Matrix;
			var m2:Matrix = new Matrix;
			var r:Matrix = new Matrix;
			r.rotate(-newAngle + tempangle);
			m1.identity();
			m2.identity();
			m1.translate(-this.x,-this.y);
			m2.translate(this.x,this.y);
			m1.concat(r);
			m1.concat(m2);
			for(var i:int = 0; i < _seatList.length; ++i)
			{	
				var fur:FurnitureBase = _seatList[i];
				var resultPoint:Point  = m1.transformPoint(new Point(fur.x,fur.y));
				
				fur.x = resultPoint.x;
				fur.y = resultPoint.y;
				fur.angle += newAngle - tempangle;
			}
			
			_accessibleBox = buildAccessOBB(x,y,_blockWidth,_blockLength);
			
		}
		
		public function get seatList():Vector.<FurnitureBase>
		{
			return _seatList;
		}
		
		override public function get width():Number
		{
			return _blockWidth;
		}
		override public function get length():Number
		{
			return _blockLength;
		}
		
		override public function get furVector():Vector.<FurnitureBase>
		{
			return _seatList;
		}
	}
}